# Cargo modulo para hacer ploteo
import pylab as p
import math
import sys, os
import numpy

# Necesario para generar datos de test
from log import *
import math
import random


from globalVar import GLOBAL_VAR, LOGS, HISTOGRAM

HIST_NMBR = 0

def main(file=None):
    global GLOBAL_VAR
    
    #if file_name == None:
        
    # Abro archivo de log con datos de posiciones, velocidades y fuerzas
    input = open (file, 'r')
    
    # Defino segundo
    segundo = 1/GLOBAL_VAR['dt']
    
    # iterador de tiempo
    time = 0 
    # para guardar las posiciones de los agentes en un determinado t
    positions = []
    last_hist = []
    distances = []
    t = []
    FIRST = False
    for line in input.readlines():
        if ';' in line:
            continue
        # leo los valores mientras el time sea el mismo
        data = line.split(',')
        #print 'DATA : ', data
        if int(data[0]) == time:
            x = float(data[1])
            y = float(data[2])
            positions.append([x,y])
            #print 'posicion de agente '+str(time)+' : '+str([x,y])
        else:
            #if time % (segundo / 2) == 0: # Si paso medio segundo
                # genero datos de histograma
                #hist, bins_edges = histogram(positions)
                # guardo dato de histograma
                #f_hist.write(str(hist)+'\n')
                
            if time % ( .15 * segundo ) == 0: 
                hist, bins_edges = histogram_plot(positions,bins=20, file_name=file)
                print 'Hago histograma!'
                
                # para hacer histograma normalizado
                #hist, bins_edges = histogram(positions, normalize=True)
                
                if FIRST:
                    dist = histogram_distance(hist, last_hist)
                    distances.append(dist)
                    t.append(time/segundo)
                else:
                    #print 'FIRST : ',FIRST
                    FIRST = True
                last_hist = hist
                
            # Aumento iterador
            time += 1
            positions = []
    
    p.cla()
    p.title('Distacia de Histogramas vs Tiempo')
    p.xlabel('Time (seg)')
    p.ylabel('Distancia')
    p.plot(t, distances)
    p.savefig(file+'_Dist_vs_Time.png')
    #p.show()

def rand_pos_on_circle(R):
    # Genero distancia al azar del centro del circulo
    r = R*random.random()
    
    # Genero un angulo al azar
    theta = 2*math.pi*random.random()
    
    # Calculo las coordenadas del punto
    x = r*math.cos(theta)
    y = r*math.sin(theta)
    
    # Devuelvo coordenadas del punto generado
    return x, y

# Desc: Funcion que toma un N y dos coordenadas 'center_x' y 'center_y'
#       y genera posiciones al azar en un cuadrado de lado L=N*l_a 
#       y centro en ('center_x', 'center_y')
# Ret: Coordenadas de la posicion al azar generada
def rand_pos_on_square(L):
    # Calculo las coordenadas del punto
    x = L*random.random()
    y = L*random.random()
    
    # Devuelvo coordenadas del punto generado
    return x, y

def generador_datos():
    R=L=10
    
    ret = Log('testing')
    for i in range(301):
        for j in range(40):
            if i < 100 or i >= 200:
                # Genero posiciones al azar en circulo de R=10
                print 'Generando con circulos ',i
                x, y = rand_pos_on_circle(R)
            else:
                print 'Generando con cuadrados ',i
                x, y = rand_pos_on_square(L)
            ret.update(str(i)+','+str(x)+','+str(y))
        
    ret.file.close()
            

# Desc: Calcula la distancia entre dos histogramas
# Input: 2 histogramas normalizados
# Output: Distancia entre los histogramas
def histogram_distance(hist1, hist2):
    
    if len(hist1)!=len(hist2):
        print "Error: histogram_distance(): Distintas longitudes de histogramas"
        return -1
    
    # Variable para guardar la sumatoria
    sum = 0
    for i in range(len(hist1)):
        
        # Calculo el denominador
        denom = hist1[i] + hist2[i]
        
        # Si es 0 no lo tengo en cuenta para la sumatoria
        if denom != 0:
            # Hago la sumatoria
            sum += ( ( hist1[i] - hist2[i] )**2 ) / denom
        
    dist = .5 * sum
    
    return sum
    
def dist(i,j):
    x = i[0] - j[0]
    y = i[1] - j[1]
    
    dist = math.hypot(x,y)
    
    return dist

def histogram(values, bins=10, normalize=False):
    # Variable para los valores del histograma
    ret = []
    
    # Calculo distancia para todo par i,j (i!=j) sin repetir los j,i
    for i in range(len(values)):
        for j in range(i+1,len(values),1):
            # Calculo distancia de i a j
            d = dist(values[i], values[j])
            ret.append(d)
    
    # Creo histograma
    hist, bins_edges = numpy.histogram(ret, bins, normed=normalize, new=True)
    
    # Devuelvo el histograma y los limites de los bins
    return hist, bins_edges


def histogram_plot(agentes, bins=10, normalized=True,file_name=None):
    global LOGS, HIST_NMBR
    
    # Variable para los valores del histograma
    ret = []
    if file_name==None:
        name = LOGS['log'].name
    else:
        name = file_name
    
    # Calculo distancia para todo par i,j (i!=j) sin repetir los j,i
    for i in range(len(agentes)):
        for j in range(i+1,len(agentes),1):
            # Calculo distancia de i a j
            d = dist(agentes[i], agentes[j])
            ret.append(d)
    
    # Creo histograma
    hist, bins_edges, z = p.hist(ret,bins=bins, normed=normalized)
    
    
    # Cargo labels al ploteo para las coordenadas X e Y
    p.xlabel('Distance')
    p.ylabel('Count')
    p.title('Histograma')
    
    # Genero path donde se guardaran los plots de los histogramas
    path = name.split('/')
    path_name = '/'.join(path[:-1])+'/'+HISTOGRAM
    
    # Veo si existe el path path_name
    if not os.access(path_name, os.F_OK):
            # Creo el directorio pues no existe
            os.mkdir(path_name)
            
    # Guardo plot de histograma
    p.savefig(path_name+'/'+path[-1]+'_HIST_'+str(HIST_NMBR)+'.png')
    
    # Aumento el contador de los plots para histograma.
    # Sirve para no pisar otros histogramas y cambiar nombre y para hacer
    # pelicula con la secuencia de .png generados
    HIST_NMBR += 1
    
    # Limpio los ejes
    p.cla() 
    
    # Devuelvo el histograma y los limites de los bins
    return hist, bins_edges


if __name__ == "__main__":
    main(sys.argv[1])
    

